using System;
using System.Collections.Generic;
using System.IO;

namespace Nyanimals
{
    /// <summary>
    /// Manages and instances all Meshes.
    /// </summary>
	public sealed class CMeshManager
	{
		private static readonly CMeshManager instance = new CMeshManager();
		private List<CMesh> Meshes;
        private CMeshManager ()
		{
			Meshes = new List<CMesh>();
		}
		
        /// <summary>
        /// Gets the instance.
        /// </summary>
        /// <value>
        /// The instance.
        /// </value>
		public static CMeshManager Instance
		{
			get { return instance;}
		}
		
        /// <summary>
        /// Adds the mesh.  Be sure to take advantage of the <see cref="Nyanimals.CMeshManager.CheckMesh"/> function.
        /// </summary>
        /// <returns>
        /// The mesh index.
        /// </returns>
        /// <param name='mesh'>
        /// Mesh to add.
        /// </param>
        public int AddMesh(CMesh mesh)
        {
            int meshIndex = Meshes.Count;
            Meshes.Add(mesh);
            
            return meshIndex;        
        }
        
        /// <summary>
        /// Checks if a mesh exists by name.
        /// </summary>
        /// <returns>
        /// The mesh index.
        /// </returns>
        /// <param name='szName'>
        /// Mesh name.
        /// </param>
        public int CheckMesh(string szName)
        {
            // determine if a mesh was already loaded
            for(int meshIndex = 0; meshIndex < Meshes.Count; ++meshIndex)
            {
                if(Meshes[meshIndex].Name == szName)
                {
                    return meshIndex;
                }
            }
            
            return -1;
        }
        
        
        /// <summary>
        /// Loads the mesh.
        /// </summary>
        /// <returns>
        /// The mesh index.
        /// </returns>
        /// <param name='szName'>
        /// Mesh name.
        /// </param>
        /// <exception cref='NullReferenceException'>
        /// Is thrown when the filename isnt a valid mesh file
        /// </exception>
		public int LoadMesh(string szName)
		{
            string szFullPath = "/Application/Resources/Models/" + szName;
			int returnIndex = CheckMesh(szFullPath);
            if(returnIndex == -1)
            {
    			// add the mesh
    			returnIndex = Meshes.Count;
                
                // determin the type of mesh we are
                BinaryReader read = new BinaryReader(File.Open(szFullPath,FileMode.Open, FileAccess.Read));                
                string header = new string(read.ReadChars(5));
                
                CMesh mesh = null;
                if( header == "SMESH")
                {
                    mesh = new CMesh();
                }
                else if( header == "DMESH")
                {
                    mesh = new CSkeletalMesh();
                }
                
                if(mesh == null)
                {
                    throw new NullReferenceException("mesh not loaded: " + szName);
                }
                
                mesh.Load(szFullPath, read);
                read.Close();
                
    			Meshes.Add(mesh);
			}
			return returnIndex;
			
		}
		
        /// <summary>
        /// Gets the mesh.
        /// </summary>
        /// <param name='meshIndex'>
        /// Mesh index.
        /// </param>
        /// <param name='mesh'>
        /// Mesh.
        /// </param>
        public void GetMesh(int meshIndex, out CMesh mesh)
        {
            mesh = Meshes[meshIndex];
        }
        /// <summary>
        /// Gets the mesh.
        /// </summary>
        /// <returns>
        /// The mesh.
        /// </returns>
        /// <param name='meshIndex'>
        /// Mesh index.
        /// </param>
        public CMesh GetMesh(int meshIndex)
        {
            return Meshes[meshIndex];
        }
		
	}
}

